/*
 * CAudioManager.cpp
 *
 *  Created on: Sep 6, 2011
 *      Author: welcome
 */

#include "CAudioManager.h"
#include "CMediaManager.h"
#include "CMediaSound.h"

namespace GGEngine {

unsigned int CAudioManager::m_index = 0;
AudioData_t CAudioManager::m_data;

/* Initialize */
int CAudioManager::init() {
	/* init SLES */
	if (CAudioPresenter::initializeEngine() != 0) {
		return -1;
	}
	m_index = 0;
	m_data.next = NULL;
	return 0;
}

/* Release all resources */
void CAudioManager::destroy() {
	AudioData_t *p;
	AudioData_t *pp;
	for (pp = m_data.next; pp != NULL;) {
		p = pp->next;
		deleteAudioData(pp);
		pp = p;
	}
	CAudioPresenter::releaseEngine();
}

/* Delete data */
void CAudioManager::deleteAudioData(AudioData_t* p) {
	UTIL_SAFE_DELETE(p->sound);
	UTIL_SAFE_DELETE(p->audio);
	UTIL_SAFE_DELETE(p);
}

/**
 Start playing the audio source specified by 'location' with looping enabled.
 'cnt' specifies the number of repeating; -1 means "endless" looping.
 */
int CAudioManager::playAudio(const char* location, int cnt) {
	AudioData_t *pp;
	AudioData_t *p = new AudioData_t();
	p->next = NULL;
	p->index = m_index;
	p->cnt = cnt;
	m_index++;

	p->sound = CMediaManager::getSound(location);

	p->audio = new CAudioPresenter();
	p->audio->setSound(p->sound);
	p->audio->play();

	if (cnt == -1) {
		p->audio->setLoop(true);
	}

	for (pp = &m_data; pp->next != NULL; pp = pp->next)
		;
	pp->next = p;

	return p->index;
}

/* Start playing the audio source specified by 'location' with looping enabled */
int CAudioManager::playLoopAudio(const char* location) {
	playAudio(location, -1);
	return 0;
}

/* Stop and release the audio data */
void CAudioManager::stopLoopAudio(int index) {
	AudioData_t *p = NULL;
	AudioData_t *pp = NULL;
	for (p = &m_data; p != NULL; p = p->next) {
		if (!p->next) {
			break;
		}
		if (p->next->index == index) {
			break;
		}
	}
	if (!p) {
		return;
	}
	pp = p->next;
	p->next = pp->next;
	deleteAudioData(pp);
}

/* Pause */
void CAudioManager::pause(int index) {
	AudioData_t *p = NULL;
	for (p = m_data.next; p != NULL; p = p->next) {
		if (!p) {
			break;
		}
		if (p->index == index) {
			break;
		}
	}
	if (!p) {
		return;
	}

	p->audio->pause();
}

/* Restart */
void CAudioManager::resume(int index) {
	AudioData_t *p = NULL;
	for (p = m_data.next; p != NULL; p = p->next) {
		if (!p) {
			break;
		}
		if (p->index == index) {
			break;
		}
	}
	if (!p) {
		return;
	}

	p->audio->restart();
}

/* Update the states of all players */
void CAudioManager::skiptime() {
	SLuint32 state;
	AudioData_t *p = NULL;
	for (p = m_data.next; p != NULL; p = p->next) {
		if (p->cnt != -1) {
			state = p->audio->getPlayState();
			if (state == SL_PLAYSTATE_STOPPED || state == SL_PLAYSTATE_PAUSED) {
				p->cnt--;
				if (p->cnt == 0) {
					stopLoopAudio(p->index);
					break;
				} else {
					p->audio->play();
				}
			}
		}
	}
}

} /* namespace GGEngine */
